package com.joker.web.controller.orange;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.joker.common.constant.Constants;
import com.joker.common.core.controller.BaseController;
import com.joker.common.core.domain.R;
import com.joker.common.core.domain.entity.SysUser;
import com.joker.common.core.domain.model.LoginBody;
import com.joker.common.core.domain.model.RegisterBody;
import com.joker.orange.domain.UserInfo;
import com.joker.orange.domain.bo.UserInfoBo;
import com.joker.orange.domain.vo.UserInfoVo;
import com.joker.orange.service.IInviteCodeService;
import com.joker.orange.service.IUserInfoService;
import com.joker.orange.service.LoginService;
import com.joker.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@Validated
@RequiredArgsConstructor
@RestController()
public class AppLoginController extends BaseController {

    private final IInviteCodeService inviteCodeService;
    private final IUserInfoService userInfoService;
    private final ISysUserService sysUserService;
    private final LoginService loginService;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @SaIgnore
    @PostMapping("/loginForApp")
    public R<Map<String, Object>> login(@Validated @RequestBody LoginBody loginBody) {
        Map<String, Object> ajax = new HashMap<>();
        // 生成令牌 type 0-未加密、1-加密
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), "0");
        ajax.put(Constants.TOKEN, token);
        return R.ok(ajax);
    }

    /**
     * 游客默认注册
     * deviceId 设备号
     * inviteCode 邀请码
     */
    @SaIgnore
    @PostMapping("/touristRegister")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, Object>> touristRegister(@RequestBody JSONObject jsonObject) {
        if (ObjectUtil.isEmpty(jsonObject.getStr("deviceId"))) {
            return R.fail("设备号为空！");
        }
        Map<String, Object> ajax = new HashMap<>();
        UserInfoBo userInfoBo = new UserInfoBo();
        userInfoBo.setDeviceId(jsonObject.getStr("deviceId"));
        UserInfoVo userInfoVo = userInfoService.queryUserInfo(userInfoBo);
        if (ObjectUtil.isEmpty(userInfoVo)) {

            RegisterBody user = new RegisterBody();
            user.setUsername(jsonObject.getStr("deviceId"));
            user.setPassword("123456");
            user.setDeviceId(jsonObject.getStr("deviceId"));
            user.setInviteCode(jsonObject.getStr("inviteCode"));
            return getRegister(user, "0");

        } else {
            // 生成令牌
            String token = loginService.login(userInfoVo.getAccount(), userInfoVo.getPassword(), "1");
            ajax.put(Constants.TOKEN, token);
            return R.ok(ajax);
        }
    }

    /**
     * 用户注册
     */
    @SaIgnore
    @PostMapping("/register")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, Object>> register(@Validated @RequestBody RegisterBody registerBody) {
        return getRegister(registerBody, "1");
    }

    /**
     *
     * @param registerBody
     * @param isYouKe 是否游客（0-是、1-否）
     * @return
     */
    private R<Map<String, Object>> getRegister(RegisterBody registerBody, String isYouKe) {
        UserInfo userByDeviceId = userInfoService.queryUserByDeviceId(registerBody.getDeviceId());
        if (ObjectUtil.isNotEmpty(userByDeviceId)) {
            // 设备号存在绑定注册关系
            UserInfo updateUserInfo = new UserInfo();
            updateUserInfo.setId(userByDeviceId.getId());
            updateUserInfo.setAccount(registerBody.getUsername());
            updateUserInfo.setNickName(registerBody.getUsername());
            updateUserInfo.setPassword(BCrypt.hashpw(registerBody.getPassword()));
            updateUserInfo.setIsYouKe(isYouKe);
            userInfoService.updateUserInfo(updateUserInfo);

            Map<String, Object> ajax = new HashMap<>();
            // 生成令牌
            String token = loginService.login(registerBody.getUsername(), registerBody.getPassword(), "0");
            ajax.put(Constants.TOKEN, token);
            return R.ok(ajax);
        }

        if ("1".equals(isYouKe)) {
            if (!registerBody.getPassword().equals(registerBody.getAgentPassword())) {
                return R.fail("倆次輸入密码不一致！");
            }
        }

        // 没有邀请码
        if (ObjectUtil.isEmpty(registerBody.getInviteCode())) {
            UserInfo userInfo = getUserInfo(registerBody, isYouKe);
            userInfo.setSuperiorType("1");
            userInfoService.insertUserInfo(userInfo);
        } else {
            // 有邀请码
            SysUser user = sysUserService.selectUserByInviteCode(registerBody.getInviteCode());
            if (ObjectUtil.isNotEmpty(user)) {
                UserInfo userInfo = getUserInfo(registerBody, isYouKe);

                userInfo.setSpreadId(String.valueOf(user.getUserId()));
                if ("0".equals(user.getIsAgent())) {
                    userInfo.setSuperiorType("0");
                } else {
                    userInfo.setSuperiorType("2");
                }

                userInfoService.insertUserInfo(userInfo);
            } else {
                UserInfo superiorUser = userInfoService.querySuperior(registerBody.getInviteCode());

                UserInfo userInfo = getUserInfo(registerBody, isYouKe);

                userInfo.setSpreadId(String.valueOf(superiorUser.getId()));
                userInfo.setSuperiorType("1");

                userInfoService.insertUserInfo(userInfo);
            }
        }

        Map<String, Object> ajax = new HashMap<>();
        // 生成令牌
        String token = loginService.login(registerBody.getUsername(), registerBody.getPassword(), "0");
        ajax.put(Constants.TOKEN, token);
        return R.ok(ajax);
    }

    private UserInfo getUserInfo(RegisterBody registerBody, String isYouKe) {
        UserInfo userInfo = new UserInfo();
        userInfo.setNickName(registerBody.getUsername());
        userInfo.setAccount(registerBody.getUsername());
        userInfo.setPassword(BCrypt.hashpw(registerBody.getPassword()));
        userInfo.setDeviceId(registerBody.getDeviceId());
        String inviteCode = inviteCodeService.selectInviteCodeByRedis();
        userInfo.setInviteCode(inviteCode);
        userInfo.setShortVideoCount("0");
        userInfo.setLongVideoCount("0");
        userInfo.setIsYouKe(isYouKe);
        inviteCodeService.updateInviteCode(inviteCode);
        return userInfo;
    }
}
